﻿using log4net.Appender;
using log4net.Core;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MSH.LogClient
{
    /// <summary>
    /// log4net自定义日志Appender
    /// 负责将日志存储进本地LiteDB
    /// </summary>
    public class MshLog4netSocketAppender : AppenderSkeleton
    {
        private static object obj = new object();

        /// <summary>
        /// 单例模式-一个Appender拥有一个守护者
        /// 客户端守护者
        /// </summary>
        private ILogClientDaemon _LogClientDaemon;
        internal ILogClientDaemon LogClientDaemon
        {
            get
            {
                if (_LogClientDaemon == null)
                {
                    var port = int.Parse(this.ServerPort);
                    _LogClientDaemon = new LogClientDaemon(this);
                }
                return _LogClientDaemon;
            }
        }

        #region 配置属性

        /// <summary>
        /// 日志服务器地址
        /// </summary>
        public string ServerHost { get; set; }
        /// <summary>
        /// 日志服务器端口
        /// </summary>
        public string ServerPort { get; set; }
        /// <summary>
        /// 上传模式
        /// </summary>
        public string Mode { get; set; } = "tcp";
        /// <summary>
        /// 默认业务位置
        /// </summary>
        public string DefaultBusinessPosition { get; set; }
        /// <summary>
        /// AppId
        /// </summary>
        public string AppId { get; set; }
        /// <summary>
        /// 密钥
        /// </summary>
        public string Secrect { get; set; }
        /// <summary>
        /// Socket协议起止符
        /// </summary>
        public string BeginMark { get; set; }
        /// <summary>
        /// Socket协议结束符
        /// </summary>
        public string EndMark { get; set; }
        /// <summary>
        /// 运行模式 
        /// S:只保存本地 U:只上传 SU:本地保存并上传
        /// </summary>
        //public string RunMode { get; set; }

        #endregion

        protected override void Append(LoggingEvent loggingEvent)
        {
            SetLogProperty(loggingEvent);
            var logRequest = loggingEvent.ToLiteDbData(this.Name);
            LogClientDaemon.ToQueue(logRequest);
        }

        protected override void Append(LoggingEvent[] loggingEvents)
        {
            loggingEvents.ToList().ForEach(a =>
            {
                SetLogProperty(a);
                var logRequest = a.ToLiteDbData(this.Name);
                LogClientDaemon.ToQueue(logRequest);
            });
            base.Append(loggingEvents);
        }

        protected void SetLogProperty(LoggingEvent loggingEvent)
        {
            loggingEvent.Properties[nameof(ServerHost)] = ServerHost;
            loggingEvent.Properties[nameof(ServerPort)] = ServerPort;
            loggingEvent.Properties[nameof(Mode)] = Mode;
            loggingEvent.Properties[nameof(AppId)] = AppId;
            loggingEvent.Properties[nameof(Secrect)] = Secrect;
            loggingEvent.Properties[nameof(DefaultBusinessPosition)] = DefaultBusinessPosition;
            loggingEvent.Properties[nameof(BeginMark)] = BeginMark;
            loggingEvent.Properties[nameof(EndMark)] = EndMark;
        }
    }
}
